#ifndef CALL_BACKS_H_
#define CALL_BACKS_H_

#include <functional>
#include <memory>

#include "netlib/base/time_stamp.h"

namespace netlib::net {

template <typename To, typename From> inline To ImplicitCast(From const& f) { return f; }

using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;

// should really belong to base/Types.h, but <memory> is not
// included there.

template <typename T> inline T* GetPointer(const std::shared_ptr<T>& ptr) { return ptr.get(); }

template <typename T> inline T* GetPointer(const std::unique_ptr<T>& ptr) { return ptr.get(); }

// Adapted from google-protobuf stubs/common.h
// see License in muduo/base/Types.h
template <typename To, typename From>
inline ::std::shared_ptr<To> DownPointerCast(const ::std::shared_ptr<From>& f) {
#ifndef NDEBUG
	assert(f == NULL || dynamic_cast<To*>(get_pointer(f)) != NULL);
#endif
	return ::std::static_pointer_cast<To>(f);
}

// All client visible callbacks go here.

class Buffer;
class TcpConnection;
class EventLoop;

using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
using TimerCallback = std::function<void()>;
using Functor = TimerCallback;
using ThreadInitCallBack = std::function<void(EventLoop*)>;
using ConnectionCallback = std::function<void(const TcpConnectionPtr&)>;
using CloseCallback = std::function<void(const TcpConnectionPtr&)>;
using WriteCompleteCallback = std::function<void(const TcpConnectionPtr&)>;
using HighWaterMarkCallback = std::function<void(const TcpConnectionPtr&, size_t)>;
using MessageCallback = std::function<void(const TcpConnectionPtr&, Buffer*, Timestamp)>;

void DefaultConnectionCallback(const TcpConnectionPtr& conn);
void DefaultMessageCallback(const TcpConnectionPtr& conn, Buffer* buffer, Timestamp receiveTime);

} // namespace netlib::net

#endif // CALL_BACKS_H_